server-side-props.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import type { GetServerSidePropsContext, GetServerSidePropsResult } from 'next';
  2. import {
  3. getServerSideI18nProps, getServerSideUserUISettingsProps, getServerSideCommonInitialProps, getServerSideCommonEachProps, isValidCommonEachRouteProps,
  4. } from '../common-props';
  5. import type { InitialProps } from '../general-page';
  6. import {
  7. getServerSideConfigurationProps, getServerSideRendererConfigProps, getServerSideSidebarConfigProps,
  8. getActivityAction, isValidInitialAndSameRouteProps,
  9. } from '../general-page';
  10. import { addActivity } from '../utils/activity';
  11. import { mergeGetServerSidePropsResults } from '../utils/server-side-props';
  12. import { NEXT_JS_ROUTING_PAGE } from './consts';
  13. import { getPageDataForInitial, getPageDataForSameRoute } from './page-data-props';
  14. import type { EachProps } from './types';
  15. const nextjsRoutingProps = {
  16. props: {
  17. nextjsRoutingPage: NEXT_JS_ROUTING_PAGE,
  18. },
  19. };
  20. export async function getServerSidePropsForInitial(context: GetServerSidePropsContext): Promise<GetServerSidePropsResult<InitialProps & EachProps>> {
  21. //
  22. // STAGE 1
  23. //
  24. const commonEachPropsResult = await getServerSideCommonEachProps(context);
  25. // Handle early return cases (redirect/notFound)
  26. if ('redirect' in commonEachPropsResult || 'notFound' in commonEachPropsResult) {
  27. return commonEachPropsResult;
  28. }
  29. const commonEachProps = await commonEachPropsResult.props;
  30. // Handle redirect destination from common props
  31. if (commonEachProps.redirectDestination != null) {
  32. return {
  33. redirect: {
  34. permanent: false,
  35. destination: commonEachProps.redirectDestination,
  36. },
  37. };
  38. }
  39. //
  40. // STAGE 2
  41. //
  42. const [
  43. commonInitialResult,
  44. userUIResult,
  45. serverConfigResult,
  46. rendererConfigResult,
  47. sidebarConfigResult,
  48. i18nPropsResult,
  49. pageDataResult,
  50. ] = await Promise.all([
  51. getServerSideCommonInitialProps(context),
  52. getServerSideUserUISettingsProps(context),
  53. getServerSideConfigurationProps(context),
  54. getServerSideRendererConfigProps(context),
  55. getServerSideSidebarConfigProps(context),
  56. getServerSideI18nProps(context, ['translation']),
  57. getPageDataForInitial(context),
  58. ]);
  59. // Merge all results in a type-safe manner (using sequential merging)
  60. const mergedResult = mergeGetServerSidePropsResults(commonEachPropsResult,
  61. mergeGetServerSidePropsResults(commonInitialResult,
  62. mergeGetServerSidePropsResults(userUIResult,
  63. mergeGetServerSidePropsResults(serverConfigResult,
  64. mergeGetServerSidePropsResults(rendererConfigResult,
  65. mergeGetServerSidePropsResults(sidebarConfigResult,
  66. mergeGetServerSidePropsResults(i18nPropsResult,
  67. mergeGetServerSidePropsResults(pageDataResult, nextjsRoutingProps))))))));
  68. // Check for early return (redirect/notFound)
  69. if ('redirect' in mergedResult || 'notFound' in mergedResult) {
  70. return mergedResult;
  71. }
  72. const mergedProps = await mergedResult.props;
  73. // Type-safe props validation AFTER skipSSR is properly set
  74. if (!isValidInitialAndSameRouteProps(mergedProps)) {
  75. throw new Error('Invalid merged props structure');
  76. }
  77. await addActivity(context, getActivityAction(mergedProps));
  78. return mergedResult;
  79. }
  80. export async function getServerSidePropsForSameRoute(context: GetServerSidePropsContext): Promise<GetServerSidePropsResult<EachProps>> {
  81. //
  82. // STAGE 1
  83. //
  84. const commonEachPropsResult = await getServerSideCommonEachProps(context);
  85. // Handle early return cases (redirect/notFound)
  86. if ('redirect' in commonEachPropsResult || 'notFound' in commonEachPropsResult) {
  87. return commonEachPropsResult;
  88. }
  89. const commonEachProps = await commonEachPropsResult.props;
  90. // Handle redirect destination from common props
  91. if (commonEachProps.redirectDestination != null) {
  92. return {
  93. redirect: {
  94. permanent: false,
  95. destination: commonEachProps.redirectDestination,
  96. },
  97. };
  98. }
  99. //
  100. // STAGE 2
  101. //
  102. // Get page data
  103. const sameRoutePageDataResult = await getPageDataForSameRoute(context);
  104. // Merge results in a type-safe manner
  105. const mergedResult = mergeGetServerSidePropsResults(commonEachPropsResult,
  106. mergeGetServerSidePropsResults(sameRoutePageDataResult, nextjsRoutingProps));
  107. // Check for early return (redirect/notFound)
  108. if ('redirect' in mergedResult || 'notFound' in mergedResult) {
  109. return mergedResult;
  110. }
  111. // Validate the merged props have all required properties
  112. if (!isValidCommonEachRouteProps(mergedResult.props)) {
  113. throw new Error('Invalid same route props structure');
  114. }
  115. // -- TODO: persist activity
  116. // const mergedProps = await mergedResult.props;
  117. // // Type-safe props validation AFTER skipSSR is properly set
  118. // if (!isValidSameRouteProps(mergedProps)) {
  119. // throw new Error('Invalid same route props structure');
  120. // }
  121. // await addActivity(context, getActivityAction(mergedProps));
  122. return mergedResult;
  123. }